<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>函数属性、方法与构造函数</title>
</head>

<body>
  <script>
    // apply()和call()
    // function sum(num1, num2) {
    //   return num1 + num2;
    // }
    // function callSum1(num1, num2) {
    //   console.log(arguments);
    //   console.log(this);
    //   return sum.apply(this, arguments);//传入arguments对象
    // }
    // function callSum2(num1, num2) {
    //   return sum.apply(callSum2, [num1, num2]);//传入数组
    // }
    // console.log(callSum1(10, 10));
    // console.log(callSum2(10, 20));

    // window.color = "red";
    // var o = { color: "blue" };
    // function sayColor() {
    //   console.log(this.color);
    // }
    // sayColor();   //red
    // sayColor.call(window);   //red
    // sayColor.call(this);   //red
    // sayColor.call(o);    //blue

    function trace(o, m) {
      // debugger
      // console.log(m);
      // console.log(o);
      let original = o[m];
      // console.log(original);
      // console.log(o[m]);
      o[m] = function (...args) {
        console.log(this);
        console.log(args);
        console.log(new Date(), "Entering:", m);
        let result = original?.apply(this, args)
        console.log(result);
        console.log(new Date(), "Exiting:", m);
        return result;
      }
    //  return o[m]
    }
    let a = {
      benchmark(n) {
        let sum = 0;
        for (let i = 1; i <= n; i++) sum += i;
        return sum
      }
    }
    console.log(trace(a, 'benchmark'));
    console.log(a.benchmark(5));



    // bind()方法
    function f(y) { return this.x + y }
    let o1 = { x: 1 };
    let g = f.bind(o1);//this指向o 相当于o1.f
    console.log(g(2));
    console.log(f.call(o1, 3));
    console.log(f.apply(o1, [5]));
    // bind是返回绑定this之后的函数，apply、call 则是立即执行
    // 三者都可以传参，但是apply是数组，而call是参数列表，且apply和call是一次性传入参数，而bind可以分为多次传入
  </script>
</body>

</html>